package com.whz.iplocation.ipregion.search.db;

import com.whz.iplocation.utils.ToolUtils;
import lombok.Data;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

/**
 * IP定位数据文件的二进制格式文件
 * <a href="https://blog.dnomd343.top/qqwry.dat-analyse/">QQWry.dat文件解析</a>
 *
 * @author whz
 */
@Data
@Slf4j
public class CwFile {
    private static final String CZIP = "CZIP";
    private final byte[] data;

    private String mark;
    private long version;
    private long fixMark;
    private long fileSize;
    private long sumCheck;
    private long secret;
    private String versionInfo;
    private String link;

    public CwFile(final byte[] data) {
        this.data = data;
        this.mark = convertToString(0, 4, StandardCharsets.UTF_8.name());
        if (!CZIP.equalsIgnoreCase(mark)) {
            throw new RuntimeException("file header not 'CZIP',it`s" + mark);
        }
        this.version = readInt(4);
        this.fixMark = readInt(8);
        this.fileSize = readInt(12);
        this.sumCheck = readInt(16);
        this.secret = readInt(20);
        this.versionInfo = readVersionInfo();
        this.link = readLink();
        log.info("CwFile Version:{},link:{}", this.versionInfo, this.link);
    }

    private String readLink() {
        return convertToString(148, 128, StandardCharsets.US_ASCII.name());
    }

    public long readInt(int offset) {
        return ToolUtils.read4ByteAsLong(data, offset);
    }

    public byte[] concat(final int offset, final int length) {
        byte[] target = new byte[length];
        System.arraycopy(data, offset, target, 0, length);
        return target;
    }

    @SneakyThrows
    private String readVersionInfo() {
        return convertToString(24, 128, "GBK");
    }

    private String convertToString(final int offset, final int length, String encoder) {
        byte[] d = concat(offset, length);
        return new String(d, Charset.forName(encoder));
    }
}